using RAG.Application.Interfaces;
using System.Text;
using Microsoft.Extensions.Logging; // This using statement is needed for ILogger
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
using UglyToad.PdfPig;

namespace RAG.Application.Services;

/// <summary>
/// 文档处理服务实现
/// </summary>
public class DocumentProcessingService : IDocumentProcessingService
{
    private readonly ILogger<DocumentProcessingService> _logger;

    public DocumentProcessingService(ILogger<DocumentProcessingService> logger)
    {
        _logger = logger;
    }

    /// <summary>
    /// 处理文档内容
    /// </summary>
    public async Task<string> ExtractTextAsync(string filePath, string fileType)
    {
        try
        {
            _logger.LogInformation("开始提取文档内容: {FilePath}, 类型: {FileType}", filePath, fileType);

            // 根据文件类型选择不同的处理方式
            switch (fileType.ToLower())
            {
                case ".txt":
                    return await File.ReadAllTextAsync(filePath);
                
                case ".md":
                    return await File.ReadAllTextAsync(filePath);
                
                case ".json":
                    return await File.ReadAllTextAsync(filePath);
                
                case ".xml":
                    return await File.ReadAllTextAsync(filePath);
                
                case ".csv":
                    return await File.ReadAllTextAsync(filePath);
                
                case ".docx":
                    return await ExtractDocxTextAsync(filePath);

                case ".pdf":
                    return await ExtractPdfTextAsync(filePath);
                
                default:
                    _logger.LogWarning("不支持的文件类型: {FileType}", fileType);
                    return await File.ReadAllTextAsync(filePath); // 默认按文本处理
            }
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "提取文档内容失败: {FilePath}", filePath);
            throw new InvalidOperationException($"提取文档内容失败: {ex.Message}");
        }
    }

    private Task<string> ExtractDocxTextAsync(string filePath)
    {
        try
        {
            var stringBuilder = new StringBuilder();
            using (var doc = WordprocessingDocument.Open(filePath, false))
            {
                var body = doc.MainDocumentPart?.Document?.Body;
                if (body != null)
                {
                    // 段落
                    foreach (var paragraph in body.Descendants<Paragraph>())
                    {
                        var text = paragraph.InnerText;
                        if (!string.IsNullOrWhiteSpace(text))
                        {
                            stringBuilder.AppendLine(text.Trim());
                        }
                    }
                }
            }
            return Task.FromResult(stringBuilder.ToString());
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "DOCX 文本提取失败: {FilePath}", filePath);
            throw new InvalidOperationException($"DOCX 文本提取失败: {ex.Message}");
        }
    }

    private Task<string> ExtractPdfTextAsync(string filePath)
    {
        try
        {
            var sb = new StringBuilder();
            using (var pdf = PdfDocument.Open(filePath))
            {
                foreach (var page in pdf.GetPages())
                {
                    var words = page.GetWords();
                    foreach (var word in words)
                    {
                        if (!string.IsNullOrWhiteSpace(word.Text))
                        {
                            sb.Append(word.Text).Append(' ');
                        }
                    }
                    sb.AppendLine();
                }
            }
            return Task.FromResult(sb.ToString());
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "PDF 文本提取失败: {FilePath}", filePath);
            throw new InvalidOperationException($"PDF 文本提取失败: {ex.Message}");
        }
    }

    /// <summary>
    /// 分块文档内容
    /// </summary>
    public async Task<List<string>> SplitIntoChunksAsync(string content, int chunkSize = 1000)
    {
        try
        {
            _logger.LogInformation("开始分块文档内容，块大小: {ChunkSize}", chunkSize);

            var chunks = new List<string>();
            var sentences = content.Split(new[] { '.', '!', '?', '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries);
            
            var currentChunk = new StringBuilder();
            
            foreach (var sentence in sentences)
            {
                var trimmedSentence = sentence.Trim();
                if (string.IsNullOrEmpty(trimmedSentence)) continue;

                if (currentChunk.Length + trimmedSentence.Length > chunkSize && currentChunk.Length > 0)
                {
                    chunks.Add(currentChunk.ToString().Trim());
                    currentChunk.Clear();
                }

                currentChunk.Append(trimmedSentence).Append(". ");
            }

            if (currentChunk.Length > 0)
            {
                chunks.Add(currentChunk.ToString().Trim());
            }

            _logger.LogInformation("文档分块完成，共生成 {ChunkCount} 个块", chunks.Count);
            return chunks;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "分块文档内容失败");
            throw new InvalidOperationException($"分块文档内容失败: {ex.Message}");
        }
    }

    /// <summary>
    /// 生成文档摘要
    /// </summary>
    public async Task<string> GenerateSummaryAsync(string content)
    {
        try
        {
            _logger.LogInformation("开始生成文档摘要");

            // 简单的摘要生成逻辑
            var sentences = content.Split(new[] { '.', '!', '?' }, StringSplitOptions.RemoveEmptyEntries);
            var summarySentences = sentences.Take(3).ToArray(); // 取前3句话作为摘要
            
            var summary = string.Join(". ", summarySentences) + ".";
            
            _logger.LogInformation("文档摘要生成完成，长度: {SummaryLength}", summary.Length);
            return summary;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "生成文档摘要失败");
            throw new InvalidOperationException($"生成文档摘要失败: {ex.Message}");
        }
    }

    /// <summary>
    /// 验证文档格式
    /// </summary>
    public bool ValidateFileFormat(string fileName, string contentType)
    {
        var supportedTypes = GetSupportedFileTypes();
        var fileExtension = Path.GetExtension(fileName).ToLower();
        
        var isValid = supportedTypes.Contains(fileExtension) || 
                     supportedTypes.Contains(contentType.ToLower());
        
        _logger.LogInformation("文件格式验证: {FileName}, {ContentType}, 结果: {IsValid}", 
            fileName, contentType, isValid);
        
        return isValid;
    }

    /// <summary>
    /// 获取支持的文件类型
    /// </summary>
    public List<string> GetSupportedFileTypes()
    {
        return new List<string>
        {
            ".txt", "text/plain",
            ".md", "text/markdown",
            ".json", "application/json",
            ".xml", "application/xml",
            ".csv", "text/csv",
            ".html", "text/html",
            ".htm", "text/html",
            ".docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
            ".pdf", "application/pdf"
        };
    }
}
